/**
* 1.mpsc 是 multiply producer single consumer 的缩写，即多生产者单消费者模式.意味着
*   rust的主要消息模式不允许一个生产者多个消费者。但rust也没有说不支持一个生产者多个消费者模式
* 2.(tx, rx) = mpsc::channel() 会返回一个元组，分别表示发送和接收者
* 3. rx有两个重要方法，分别是recv() 和 try_recv().前者会阻塞，后者不会。
* 4. 信道和所有权问题. tx.send方法会默认夺取消息的所有权，移动这个值归接收者所有.所以发送者需要拥有消息的所有权。
*    这也同时意味着，如果没有特别措施，那么发送之后，被发送的消息不能再访问了。
*    那么，我们是否宁愿 clone() 一下，然后再发送呢？是的。
*    rust的所有权系统，导致rust会把消息视为一个实物，而不是一个拷贝，意味着发送就是“脱手”、“出手”
* 5. 发送者可以关闭信道，这样接收者就会收到一个错误。
* 6. 发送者可以克隆，这样多个线程都可以发送消息。发送者虽然克隆了，但是接收者还是同一个.
  7. 这种方式是否可能存在这样的问题：后发先至。 这个问题暂时没有明确答案，因为暂时没有找到答案。据说概率很小，但不是么有？
*/
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
#[derive(Debug)]
#[allow(dead_code)]
struct Message {
    sender: String, // 发送者标识
    content: String, // 消息内容
    order: u8, // 消息序号

}

fn main() {
    // --snip--
    let (tx, rx) = mpsc::channel();   //channel() 返回一个元组，分别表示发送和接收者
    let tx1 = tx.clone();
    thread::spawn(move || {           // 移动tx1所有权到新线程中。为什么需要move？规定就是这样
        let vals = vec![
            Message{sender: String::from("x1"),content: String::from("风"),order:1},
            Message{sender: String::from("x1"),content: String::from("紧"),order:2},
            Message{sender: String::from("x1"),content: String::from("扯"),order:3},
            Message{sender: String::from("x1"),content: String::from("呼"),order:4}
        ];
        for val in vals {
            tx1.send(val).unwrap();
            println!("tx1 is sending....");
            thread::sleep(Duration::from_millis(200));
        }
    });

    thread::spawn(move || {
        let vals = vec![
            Message{sender: String::from("x0"),content: String::from("乘"),order:1},
            Message{sender: String::from("x0"),content: String::from("胜"),order:2},
            Message{sender: String::from("x0"),content: String::from("追"),order:3},
            Message{sender: String::from("x0"),content: String::from("击"),order:4}
        ];

        for val in vals {
            tx.send(val).unwrap();
            println!("tx0 is sending....");
            thread::sleep(Duration::from_millis(100));
        }
    });

    //把收到的消息分别放入到两个Vec中，以便于观察顺序。
    let mut v0 = Vec::new();
    let mut v1 = Vec::new();
    let mut qty=0;
    //利用rx的迭代器接收消息. 无需显示调用rec(),或者try_recv()，迭代器会自动调用。
    for received in rx {
        if received.sender == "x0" {
            v0.push(received);
        }
        else{
            v1.push(received);
        }
        qty += 1;
        if qty==20 { // 收到5条消息就退出循环。看看会不会有什么问题
            break;
        }
    }

    let msg0 = get_msg(v0);
    let msg1 = get_msg(v1);

    println!("从t0收到的消息是: {}", msg0);
    println!("从t1收到的消息是: {}", msg1);

    if msg0!=msg1 {
        println!("那一份消息是真的？应该信任谁？还是说都是真的？\n 如果都是真的，为什么会这样？");
    }

}

fn get_msg(msg:Vec<Message>) -> String   {
    let mut result = String::new();
    for m in msg {
        result.push_str(&m.content);
    }
    return result;
}